package com.gupao.proxydemo.orderdemo.proxy;

import com.gupao.proxydemo.orderdemo.db.DataSourceChange;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.text.SimpleDateFormat;
import java.util.Date;

@Slf4j
public class OrderServiceDynamic implements InvocationHandler {


    private Object proxyObj;

    private SimpleDateFormat yearFormat = new SimpleDateFormat("yyyy");


    /**
     * 通过反射获取被代理类接口的一个全新的代理类
     *
     * @param proxyObj
     * @return
     */
    public Object getInstance(Object proxyObj) {
        this.proxyObj = proxyObj;
        Class<?> clazz = proxyObj.getClass();
        return Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), this);
    }


    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //通过上边生成的全新代理类$Proxy0，会重写被代理类接口的所有方法，
        //而在重写的方法里会直接调用该类的invoke
        //该类的invoke方法里面，实际上又通过反射调用被代理类的方法,而且在调用被代理类方法的前后可对其增强
        log.info("before invoke");
        //insertOrder(Order order)方法只有一个参数，所以args[0]就是order对象
        before(args[0]);
        Object object = method.invoke(this.proxyObj, args);
        after();
        log.info("after invoke");
        return object;
    }

    /**
     * @param target 订单order
     */
    private void before(Object target) {
//        Integer year = Integer.valueOf(yearFormat.format(new Date()));
//
        try {
            Date createTime = (Date) target.getClass().getMethod("getCreateTime").invoke(target);
            Integer year = Integer.valueOf(yearFormat.format(createTime));
            DataSourceChange.set(year);
            log.info("jdk动态代理动态分配数据源：DB_{}", year);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }


    private void after() {
        DataSourceChange.restore();
    }
}
